# {{ ansible_managed }}

{% set request_option = item.service.haproxy_balance_type | default("http") -%}
{% if item.service.haproxy_backend_port is not defined %}
  {% set haproxy_backend_port = item.service.haproxy_port %}
{% else %}
  {% set haproxy_backend_port = item.service.haproxy_backend_port %}
{% endif -%}
{% if item.service.haproxy_check_port is not defined %}
  {% set haproxy_check_port = haproxy_backend_port %}
{% else %}
  {% set haproxy_check_port = item.service.haproxy_check_port %}
{% endif -%}

{% set vip_binds = [haproxy_bind_external_lb_vip_address] -%}
{%- if haproxy_bind_internal_lb_vip_address not in vip_binds %}
  {% set _ = vip_binds.append(haproxy_bind_internal_lb_vip_address) %}
{% endif -%}

{% for vip_address in extra_lb_vip_addresses %}
  {% set _ = vip_binds.append(vip_address) %}
{% endfor %}

{% for vip_address in extra_lb_tls_vip_addresses %}
  {% set _ = vip_binds.append(vip_address) %}
{% endfor %}

{%- if item.service.haproxy_bind is defined %}
  {% set vip_binds = item.service.haproxy_bind %}
{% endif -%}

{% for vip_bind in vip_binds %}
{% if item.service.haproxy_redirect_http_port is defined and item.service.haproxy_ssl %}
{% if (loop.index == 1 or item.service.haproxy_ssl_all_vips | default(false) | bool) %}

frontend {{ item.service.haproxy_service_name }}-redirect-front-{{ loop.index }}
bind {{ vip_bind }}:{{ item.service.haproxy_redirect_http_port }}
    mode http
    redirect scheme https if !{ ssl_fc }
{% endif %}
{% endif %}

frontend {{ item.service.haproxy_service_name }}-front-{{ loop.index }}
    bind {{ vip_bind }}:{{ item.service.haproxy_port }} {% if (item.service.haproxy_ssl | default(false) | bool) and (loop.index == 1 or vip_bind in extra_lb_tls_vip_addresses or item.service.haproxy_ssl_all_vips | default(false) | bool) %}ssl crt {{ haproxy_ssl_pem }} ciphers {{ haproxy_ssl_cipher_suite }}{% endif %}

{% if request_option == "http" %}
    option httplog
    option forwardfor except 127.0.0.0/8
{% if item.service.haproxy_http_keepalive_mode is defined %}
    option {{ item.service.haproxy_http_keepalive_mode }}
{% endif %}
{% elif request_option == "tcp" %}
    option tcplog
{% endif %}
{% if item.service.haproxy_timeout_client is defined %}
    timeout client {{ item.service.haproxy_timeout_client }}
{% endif %}
{% if item.service.haproxy_whitelist_networks is defined %}
    acl white_list src 127.0.0.1/8 {{ item.service.haproxy_whitelist_networks | join(' ') }}
    tcp-request content accept if white_list
    tcp-request content reject
{% endif %}
{% if item.service.haproxy_acls is defined %}
{%   for key, value in item.service.haproxy_acls.items() %}
    acl {{ key }} {{ value.rule }}
    use_backend {{ value.backend_name | default(item.service.haproxy_service_name) }}-back if {{ key }}
{%   endfor %}
{% endif %}
{% if (item.service.haproxy_ssl | default(false) | bool) and request_option == 'http' and (loop.index == 1 or vip_bind in extra_lb_tls_vip_addresses or item.service.haproxy_ssl_all_vips | default(false) | bool) %}
    reqadd X-Forwarded-Proto:\ https
{% endif %}
    mode {{ item.service.haproxy_balance_type }}
    default_backend {{ item.service.haproxy_service_name }}-back
{% endfor %}

{% set backend_options = item.service.haproxy_backend_options|default([]) %}
{% set backend_arguments = item.service.haproxy_backend_arguments|default([]) %}

backend {{ item.service.haproxy_service_name }}-back
    mode {{ item.service.haproxy_balance_type }}
    balance {{ item.service.haproxy_balance_alg|default("leastconn") }}
{% if item.service.haproxy_timeout_server is defined %}
    timeout server {{ item.service.haproxy_timeout_server }}
{% endif %}
    stick store-request src
    stick-table type ip size 256k expire 30m
{% if request_option == "http" %}
    option forwardfor
    option httplog
{% elif request_option == "tcp" %}
    option tcplog
{% endif %}
{% for option in backend_options %}
    option {{ option }}
{% endfor %}
{% for argument in backend_arguments %}
    {{ argument }}
{% endfor %}
{% set backend_httpcheck_options = item.service.haproxy_backend_httpcheck_options|default([]) %}
{% for option in backend_httpcheck_options %}
    http-check {{ option }}
{% endfor %}


{% for host_name in item.service.haproxy_backend_nodes %}
{% if hostvars[host_name] is defined %}
{%   set ip_addr = hostvars[host_name]['ansible_host'] %}
{% endif %}
{% set entry = [] %}
{% set _ = entry.append("server") %}
{% set _ = entry.append((host_name.name | default(host_name)) | string) %}
{% set _ = entry.append((host_name.ip_addr | default(ip_addr)) + ":" + haproxy_backend_port | string) %}
{% set _ = entry.append("check") %}
{% set _ = entry.append("port") %}
{% set _ = entry.append(haproxy_check_port | string) %}
{% set _ = entry.append("inter") %}
{% set _ = entry.append(haproxy_interval | string) %}
{% set _ = entry.append("rise") %}
{% set _ = entry.append(item.service.backend_rise|default(item.service.haproxy_backend_nodes | count | string)) %}
{% set _ = entry.append("fall") %}
{% set _ = entry.append(item.service.backend_fall|default(item.service.haproxy_backend_nodes | count | string)) %}
{% if item.service.haproxy_backend_ssl | default(False) %}
{% set _ = entry.append("ssl") %}
{% if item.service.haproxy_backend_ca %}
{% set _ = entry.append("ca-file") %}
{% set _ = entry.append(item.service.haproxy_backend_ca) %}
{% else %}
{% set _ = entry.append("verify none") %}
{% endif %}
{% endif %}
{% set backend_server_options = item.service.haproxy_backend_server_options|default([]) %}
{% for option in backend_server_options %}
{%  set _ = entry.append(option) %}
{% endfor %}
{% set backend_per_server_options = host_name.backend_server_options|default([]) %}
{% for option in backend_per_server_options %}
{%  set _ = entry.append(option) %}
{% endfor %}
    {{ entry | join(' ') }}
{% endfor %}

{% for host_name in item.service.haproxy_backup_nodes|default([]) %}
{% if hostvars[host_name] is defined %}
{%   set ip_addr = hostvars[host_name]['ansible_host'] %}
{% endif %}
{% set entry = [] %}
{% set _ = entry.append("server") %}
{% set _ = entry.append((host_name.name | default(host_name)) | string) %}
{% set _ = entry.append((host_name.ip_addr | default(ip_addr)) + ":" + haproxy_backend_port | string) %}
{% set _ = entry.append("check") %}
{% set _ = entry.append("port") %}
{% set _ = entry.append(haproxy_check_port | string) %}
{% set _ = entry.append("inter") %}
{% set _ = entry.append(haproxy_interval | string) %}
{% set _ = entry.append("rise") %}
{% set _ = entry.append(item.service.backup_rise|default(item.service.haproxy_backup_nodes | count | string)) %}
{% set _ = entry.append("fall") %}
{% set _ = entry.append(item.service.backup_fall|default(item.service.haproxy_backup_nodes | count | string)) %}
{% set _ = entry.append("backup") %}
{% if item.service.haproxy_backend_ssl | default(False) %}
{% set _ = entry.append("ssl") %}
{% if item.service.haproxy_backend_ca %}
{% set _ = entry.append("ca-file") %}
{% set _ = entry.append(item.service.haproxy_backend_ca) %}
{% else %}
{% set _ = entry.append("verify none") %}
{% endif %}
{% endif %}
{% set backend_server_options = item.service.haproxy_backend_server_options|default([]) %}
{% for option in backend_server_options %}
{%  set _ = entry.append(option) %}
{% endfor %}
{% set backend_per_server_options = host_name.backend_server_options|default([]) %}
{% for option in backend_per_server_options %}
{%  set _ = entry.append(option) %}
{% endfor %}
    {{ entry | join(' ') }}
{% endfor %}
